package handler

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"markedit/internal/model"
	"markedit/internal/service"
)

type MarkdownHandler struct {
	markdownService *service.MarkdownService
	logger          *logrus.Logger
}

func NewMarkdownHandler(markdownService *service.MarkdownService, logger *logrus.Logger) *MarkdownHandler {
	return &MarkdownHandler{
		markdownService: markdownService,
		logger:          logger,
	}
}

// ParseMarkdown 解析Markdown
// @Summary 解析Markdown
// @Description 将Markdown文本转换为HTML
// @Tags Markdown
// @Accept json
// @Produce json
// @Param request body map[string]string true "Markdown内容"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/markdown/parse [post]
func (h *MarkdownHandler) ParseMarkdown(c *gin.Context) {
	var request struct {
		Content string `json:"content" binding:"required"`
	}

	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	html, err := h.markdownService.ParseMarkdown(request.Content)
	if err != nil {
		h.logger.Errorf("Failed to parse markdown: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to parse markdown",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"html": html,
		},
		Message: "Markdown parsed successfully",
	})
}

// ParseMarkdownWithMetadata 解析Markdown并返回元数据
// @Summary 解析Markdown并返回元数据
// @Description 解析Markdown并返回HTML、字数统计、标题等元数据
// @Tags Markdown
// @Accept json
// @Produce json
// @Param request body map[string]string true "Markdown内容"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/markdown/parse-with-metadata [post]
func (h *MarkdownHandler) ParseMarkdownWithMetadata(c *gin.Context) {
	var request struct {
		Content string `json:"content" binding:"required"`
	}

	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	metadata, err := h.markdownService.ParseMarkdownWithMetadata(request.Content)
	if err != nil {
		h.logger.Errorf("Failed to parse markdown with metadata: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to parse markdown",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    metadata,
		Message: "Markdown parsed with metadata successfully",
	})
}

// GetWordCount 获取字数统计
// @Summary 获取字数统计
// @Description 获取Markdown文档的字数统计
// @Tags Markdown
// @Accept json
// @Produce json
// @Param request body map[string]string true "Markdown内容"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/markdown/word-count [post]
func (h *MarkdownHandler) GetWordCount(c *gin.Context) {
	var request struct {
		Content string `json:"content" binding:"required"`
	}

	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	wordCount := h.markdownService.GetWordCount(request.Content)

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"word_count": wordCount,
		},
		Message: "Word count retrieved successfully",
	})
}

// ValidateMarkdown 验证Markdown语法
// @Summary 验证Markdown语法
// @Description 验证Markdown文档的语法正确性
// @Tags Markdown
// @Accept json
// @Produce json
// @Param request body map[string]string true "Markdown内容"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/markdown/validate [post]
func (h *MarkdownHandler) ValidateMarkdown(c *gin.Context) {
	var request struct {
		Content string `json:"content" binding:"required"`
	}

	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	errors := h.markdownService.ValidateMarkdown(request.Content)

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"valid":  len(errors) == 0,
			"errors": errors,
		},
		Message: "Markdown validation completed",
	})
}

// PreviewMarkdown 预览Markdown
// @Summary 预览Markdown
// @Description 返回Markdown的HTML预览
// @Tags Markdown
// @Accept json
// @Produce html
// @Param request body map[string]string true "Markdown内容"
// @Success 200 {string} string "HTML内容"
// @Failure 400 {object} model.ErrorResponse
// @Router /api/markdown/preview [post]
func (h *MarkdownHandler) PreviewMarkdown(c *gin.Context) {
	var request struct {
		Content string `json:"content" binding:"required"`
	}

	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	html, err := h.markdownService.ParseMarkdown(request.Content)
	if err != nil {
		h.logger.Errorf("Failed to parse markdown: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to parse markdown",
			Message: err.Error(),
		})
		return
	}

	// 返回HTML预览
	c.Header("Content-Type", "text/html; charset=utf-8")
	c.String(http.StatusOK, html)
}

// GetMarkdownStructure 获取Markdown结构
// @Summary 获取Markdown结构
// @Description 获取Markdown文档的结构信息（标题、图表、公式等）
// @Tags Markdown
// @Accept json
// @Produce json
// @Param request body map[string]string true "Markdown内容"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/markdown/structure [post]
func (h *MarkdownHandler) GetMarkdownStructure(c *gin.Context) {
	var request struct {
		Content string `json:"content" binding:"required"`
	}

	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	metadata, err := h.markdownService.ParseMarkdownWithMetadata(request.Content)
	if err != nil {
		h.logger.Errorf("Failed to parse markdown structure: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to parse markdown structure",
			Message: err.Error(),
		})
		return
	}

	structure := map[string]interface{}{
		"headings": metadata["headings"],
		"charts":   metadata["charts"],
		"formulas": metadata["formulas"],
		"links":    metadata["links"],
		"images":   metadata["images"],
		"toc":      metadata["toc"],
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    structure,
		Message: "Markdown structure retrieved successfully",
	})
}

// ConvertMarkdown 转换Markdown格式
// @Summary 转换Markdown格式
// @Description 将Markdown转换为其他格式
// @Tags Markdown
// @Accept json
// @Produce json
// @Param request body map[string]interface{} true "转换请求"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/markdown/convert [post]
func (h *MarkdownHandler) ConvertMarkdown(c *gin.Context) {
	var request struct {
		Content string `json:"content" binding:"required"`
		Format  string `json:"format" binding:"required"`
		Options map[string]interface{} `json:"options"`
	}

	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	var result string
	var err error

	switch request.Format {
	case "html":
		result, err = h.markdownService.ParseMarkdown(request.Content)
	default:
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Unsupported format",
			Message: "Supported formats: html",
		})
		return
	}

	if err != nil {
		h.logger.Errorf("Failed to convert markdown: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to convert markdown",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"content": result,
			"format":  request.Format,
		},
		Message: "Markdown converted successfully",
	})
}

// RenderMarkdown 渲染Markdown
// @Summary 渲染Markdown
// @Description 渲染Markdown内容为HTML
// @Tags Markdown
// @Accept json
// @Produce json
// @Param request body map[string]string true "Markdown内容"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/markdown/render [post]
func (h *MarkdownHandler) RenderMarkdown(c *gin.Context) {
	var request struct {
		Content string `json:"content" binding:"required"`
	}

	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	html, err := h.markdownService.RenderToHTML(request.Content)
	if err != nil {
		h.logger.Errorf("Failed to render markdown: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to render markdown",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"html": html,
		},
		Message: "Markdown rendered successfully",
	})
}